<?php

/**
 * wechat.php
 * 微信小程序支付获取支付数据
 * Author: netman
 * DateTime:  2023/10/20 4:37
 */
class Service_Api_Payment_Wechat extends Contract_Api_Payment
{
    use Trait_Api_Common;
    use Trait_Api_Payment;

    /**
     * 获取支付数据
     * @param $params
     * @return array
     * @throws Exception
     * User: netman
     * Date: 2023/10/20 15:16
     */
    function get_pay_data($params): array
    {
        // 验证订单状态
        $order_sn = $params['ordersn'];
        // 验证订单
        $checkOrder = Model_Api_V2_Payment::ordersn_checked($order_sn);

        if ( ! $checkOrder['status']) {
            throw new Exception($checkOrder['msg']);
        }
        $orderInfo = Model_Member_Order::order_info($order_sn);

        //"0元"订单,免费产品
        if ($orderInfo['pay_price'] == 0) {
            $zero_res = $this->zero_pay($order_sn);
            if ($zero_res['status']) {
                $orderInfo['sign'] = $zero_res['data']['sign'];
                return array(
                    'is_pay' => 1,
                    'info' => $orderInfo,
                    'pay_method' => [],
                    'additional' => [],
                    'btn_title' => '查看订单'
                );
            } else {
                throw new Exception($zero_res['msg']);
            }
        }

        if ($orderInfo && $orderInfo['status'] == 1 && $orderInfo['memberid'] == $params['mid']) {
            $orderid = $orderInfo['id'];
            $totalprice = $orderInfo['payprice'];

            // 支付基础数据,兼容通过中转应用请求接口
            if ($params['authorizer_appid'] && $params['mchid']) {
                $appid = $params['authorizer_appid'];
                $mchid = $params['mchid'];
                $mchkey = $params['mchkey'];
                $site_id = $params['site_id'];
                $appsecret = $params['appsecret'];
                $notify_url = $params['notify_url'];
            } else {
                //微信小程序appid,appsecret
                $config_params = [
                    'cfg_global_client_appkey', //小程序appid
                    'cfg_global_client_appsecret', //小程序appsecret
                    'cfg_wxpay_mchid', //微信支付商户mchid
                    'cfg_wxpay_key', //微信支付商户key
                ];
                $wx_configs = Model_Sysconfig::get_configs(0, $config_params);
                $appid = $wx_configs['cfg_global_client_appkey'];
                $appsecret = $wx_configs['cfg_global_client_appsecret'];
                $mchid = $wx_configs['cfg_wxpay_mchid'];
                $mchkey = $wx_configs['cfg_wxpay_key'];
                $site_id = 0;
                //回调地址
                $notify_url = URL::base(true)."api/service/wxnotify/index";
            }


            //备注
            $attach = $site_id.'||'.$orderid;
            // 获取会员的微信小程序参数配置
            $member_third = DB::select()->from("member_third")->where("mid", "=",
                $params['mid'])->and_where("come_from", "=", "weixin")->execute()->current();

            if ($member_third && $member_third['wx_mini_openid']) {
                $openid = $member_third['wx_mini_openid'];
                // 商品描述
                $title = $orderInfo['productname'].' '.$orderInfo['suit_name'];
                $title = mb_substr($title, 0, 15);
                // 商户标记
                $tag = DB::select()->from("model")->where("id", "=", $orderInfo['typeid'])->execute()->get('pinyin');

                require_once BASEPATH."/plugins/api/vendor/weixin/lib/WxPay.Api.php";

                WxPayConfig::$appid = $appid;
                WxPayConfig::$appsecret = $appsecret;
                WxPayConfig::$mchid = $mchid;
                WxPayConfig::$key = $mchkey;

                // 设置支付数据
                $input = new WxPayUnifiedOrder();
                $input->SetBody($title); //商品描述
                $input->SetAttach($attach); //备注
                $input->SetOut_trade_no($order_sn.rand(1000, 9999)); //商户订单号
                $input->SetTotal_fee($totalprice * 100);//总金额,以分为单位
                $input->SetTime_start(date("YmdHis"));//交易起始时间
                $input->SetTime_expire(date("YmdHis", time() + 6000));//交易结束时间
                $input->SetGoods_tag($tag);//商品标记
                $input->SetNotify_url($notify_url); //异步通知
                $input->SetTrade_type("JSAPI");
                $input->SetProduct_id($order_sn);
                $input->SetOpenid($openid);
                $input->SetAppid($appid);
                $input->SetMch_id($mchid);//商户号

                try {
                    $unifiedOrderResult = WxPayApi::unifiedOrder($input, $mchkey);
                } catch (Exception $err) {
                    throw new Exception($err->getMessage());
                }

                //商户根据实际情况设置相应的处理流程
                if ($unifiedOrderResult["return_code"] == "FAIL") {
                    throw new Exception($unifiedOrderResult['return_msg']);
                    //商户自行增加处理流程

                } elseif ($unifiedOrderResult["result_code"] == "FAIL") {
                    //商户自行增加处理流程
                    throw new Exception($unifiedOrderResult['err_code_des']);
                } else {
                    $nonce_str = $unifiedOrderResult['nonce_str'];
                    $appid = $unifiedOrderResult['appid'];
                    $prepay_id = $unifiedOrderResult['prepay_id'];
                    $timeStamp = time();
                    $stringA = "appId=$appid&nonceStr=$nonce_str&package=".'prepay_id='."$prepay_id&signType=MD5&timeStamp=$timeStamp";//这里记得顺序和大小写！切记！
                    $stringSignTemp = "$stringA&key=$mchkey";
                    $paySign = md5($stringSignTemp);
                    $paySign = strtoupper($paySign);
                    $unifiedOrderResult['paySign'] = $paySign;
                    $unifiedOrderResult['package'] = 'prepay_id='.$prepay_id;
                    $unifiedOrderResult['timeStamp'] = "$timeStamp";
                    $unifiedOrderResult['is_pay'] = 0;
                    return $unifiedOrderResult;
                }
            } else {
                throw new Exception('会员信息有误');
            }
        } else {
            throw new Exception("订单信息有误");
        }
    }


}